﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Drawing;

namespace WinFormUIXMLParser
{
    public class WriteUIConfig
    {
        private string _file = "";
        private XmlDocument _xmlDoc = null;
        private XmlNode _root = null;
        private List<XButton> _listXButtons = new List<XButton>();  
        private List<XmlButtonObject> _listButtons = new List<XmlButtonObject>();   
        private CodeParser _parser = null;

        public WriteUIConfig(CodeParser parser, string file)
        {
            _parser = parser;
            _file = file; 
        }

        private void OnPrepared()
        {
            _listButtons = _parser.ParseButtons();                     
        }

        public bool CreatXmlHeader()
        {
            if (File.Exists(_file))
            {
                File.Delete(_file);
            }
            try
            {
                _xmlDoc = new XmlDocument();
                XmlDeclaration xmlDec = _xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
                _xmlDoc.AppendChild(xmlDec);
                XmlElement newElem = _xmlDoc.CreateElement("Window");
                _xmlDoc.AppendChild(newElem);
                _root = _xmlDoc.SelectSingleNode("Window");
                Func<string, string, XmlNode> insertChildNode = (name, comment) =>
                {
                    XmlElement childElem = _xmlDoc.CreateElement(name);
                    XmlNode node = _root.AppendChild(childElem);
                    // 添加注释
                    XmlComment commentNode = _xmlDoc.CreateComment(comment);
                    node.ParentNode.InsertBefore(commentNode, node);
                    return node;
                };                         
                insertChildNode("Buttons", "按钮");            
            }
            catch (System.Exception ex)
            {
                return false;
            }
            return true;
        }

        private bool AddXmlObjects<T>(string parentName, string nodeName, List<T> list) where T : new()
        {
            try
            {                        
                XmlElement parent = _root[parentName];
                Type type = typeof(T);
                for (int i = 0; i < list.Count; i++)
                {
                    XmlElement elem = _xmlDoc.CreateElement(nodeName);
                    PropertyInfo[] Properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                    foreach (PropertyInfo p in Properties)
                    {
                        string name = p.Name;
                        object oVal = p.GetValue(list[i], null);
                        if (oVal == null)
                        {
                            elem.SetAttribute(name, "");
                            continue;
                        }
                        string value = oVal.ToString();
                        if (!string.IsNullOrEmpty(value))
                        {
                            elem.SetAttribute(name, value);
                        }
                        else
                        {
                            elem.SetAttribute(name, "");
                        }
                    }
                    parent.AppendChild(elem);
                }
                return true;
            }
            catch (System.Exception ex)
            {
                return false;
            }
        }

        private void ConvertToXButtons()
        {
            _listXButtons.Clear();
            foreach (XmlButtonObject btn in _listButtons)
            {
                Size size = StaticTypes.GetSize(btn.Size);
                Point pos = StaticTypes.GetLocation(btn.Location);
                Font font = StaticTypes.GetFont(btn.Font);
                XButton xb = new XButton();
                xb.Name = btn.Name;
                xb.Text = btn.Text;
                xb.Width = size.Width.ToString();
                xb.Height = size.Height.ToString();
                xb.Top = pos.Y.ToString();
                xb.Left = pos.X.ToString();
                xb.FontSize = font.Size.ToString();
                _listXButtons.Add(xb);
            }
        }

        public bool Write(string file)
        {
            if (CreatXmlHeader())
            {
                ConvertToXButtons();
                AddXmlObjects<XButton>("Buttons", "Button", _listXButtons);               
                _xmlDoc.Save(file);
                return true;
            }
            return false;
        }

        public bool Write()
        {
            if (_parser != null)
            {
                OnPrepared();             
            }
            return Write(_file);
        }
    }
}
